<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 通用工具栏 -->
      <page-tools>
        <template #left>
          <span>总记录数: {{ total }} 条</span>
        </template>
        <template #right>
          <!--
             路由跳转携带参数
             this.$router.push({
               path: '/import',
               query: {
                 type: 'user'
               }
             })
             简化: this.$router.push('/import?type=user')
           -->
          <el-button size="small" type="warning" @click="$router.push('/import?type=user')">excel导入</el-button>
          <el-button :loading="downloadLoading" size="small" type="danger" @click="handleExcelExport">excel导出</el-button>
          <el-button size="small" type="primary" @click="showAddDialog = true">新增员工</el-button>
        </template>
      </page-tools>
      <!-- 主体内容版块 -->
      <el-card v-loading="loading" style="margin-top: 10px;">
        <!-- 表格组件 -->
        <el-table :data="list" border>
          <el-table-column label="序号" type="index" :index="indexFn" sortable="" width="100" />
          <el-table-column label="姓名" prop="username" sortable="" />
          <el-table-column label="头像" prop="staffPhoto" sortable="">
            <template #default="{row}">
              <img
                v-imgerror="errorImg"
                :src="row.staffPhoto || defaultImg"
                class="staff-photo"
                @click="handleImgClick(row.staffPhoto)"
              >
            </template>
          </el-table-column>
          <el-table-column label="手机号" prop="mobile" sortable="" />
          <el-table-column label="工号" prop="workNumber" sortable="" />
          <el-table-column label="聘用形式" prop="formOfEmployment" sortable="" :formatter="formatterEmployment" />
          <el-table-column label="部门" prop="departmentName" sortable="" />
          <el-table-column label="入职时间" sortable="">
            <template #default="{row}">
              {{ row.timeOfEntry | formatDate('YYYY/MM/DD') }}
            </template>
          </el-table-column>
          <el-table-column label="操作" sortable fixed="right" width="280">
            <template #default="{row}">
              <!--
                路由携带参数的两种方式:
                this.$router.push({
                  path: '/employees/detail',
                  query: {
                    id: 'xxx'
                  }
                })
                this.$router.push('/employees/detail?id=xxx')
                取: this.$route.query.id

                this.$router.push({
                  path: '/employees/detail',
                  params: {
                    id: 'xxx'
                  }
                })
                this.$router.push("/employees/detail/1233232")
                取: this.$route.params.id
               -->
              <el-button
                type="text"
                size="small"
                @click="$router.push(`/employees/detail/${row.id}`)"
              >查看</el-button>
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button type="text" size="small" @click="handleRole(row.id)">角色</el-button>
              <el-button type="text" size="small" @click="handleDel(row.id)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <div style="height: 60px; margin-top: 10px">
          <el-pagination
            :current-page="page"
            :page-sizes="[1,2,3,4,5,6,7,8,9,10]"
            :page-size="5"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
        <!-- 不推荐 -->
        <!-- <add-employee
          :show-dialog.sync="showAddDialog"
          @add-employee="handleAddEmployee"
        /> -->
      </el-card>

      <!-- 添加员工弹窗组件 -->
      <!-- .sycn修饰符 代表着 父组件放权给子组件可以直接修改show-dialog的值并同步 -->
      <add-employee
        :show-dialog.sync="showAddDialog"
        @add-employee="handleAddEmployee"
      />

      <!-- 弹窗展示图片 -->
      <el-dialog
        width="400px"
        title="头像二维码"
        :visible="showImgDialog"
        @close="showImgDialog=false"
      >
        <div style="text-align: center;"><canvas ref="staffCanvas" /></div>
      </el-dialog>

      <!-- 角色分配对话框 -->
      <assign-role :show-role-dialog.sync="showRoleDialog" :user-id="userId" />
    </div>
  </div>
</template>

<script>
import { reqDelEmployee, reqGetUserList } from '@/api/employees'
import employees from '@/constant/employees'
import AddEmployee from './components/AddEmployee.vue'
import dayjs from 'dayjs'
import errorImg from '@/assets/common/bigUserHeader.png'
import QRCode from 'qrcode'
import AssignRole from './components/AssignRole.vue'

export default {
  name: 'Employees',
  components: {
    AddEmployee,
    AssignRole
  },
  data() {
    return {
      page: 1, // 页码
      size: 5, // 每页条数
      list: [], // 员工列表数据
      total: 0, // 总记录数
      loading: false, // 是否显示loading圈
      showAddDialog: false, // 显示和隐藏添加弹窗
      downloadLoading: false, // 导出Excel表格loading圈
      errorImg,
      defaultImg: 'https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2146034403,1504718527&fm=26&gp=0.jpg',
      showImgDialog: false, // 是否展示图片弹窗
      showRoleDialog: false, // 显示和隐藏分配权限对话框
      userId: '' // 分配角色时传递用户id
    }
  },
  created() {
    this.getUserList()
  },
  methods: {
    // 1. 获取员工列表
    async getUserList() {
      this.loading = true

      const { data: { rows, total }} = await reqGetUserList(this.page, this.size)
      this.list = rows
      this.total = total

      this.loading = false
    },
    // 2. 页码发生变化
    handleCurrentChange(val) {
      this.page = val
      this.getUserList()
    },
    // 3. 每页显示的条数发生变化
    handleSizeChange(val) {
      this.size = val
      // 注意: 规范-->一般每页显示的条数发生变化, 会设置当前页为第一页
      this.page = 1
      this.getUserList()
    },
    // 4. 处理序号
    indexFn(index) {
      return index + 1 + (this.page - 1) * this.size
    },
    // 5. 格式化输出聘用形式
    formatterEmployment(row, column, cellValue, index) {
      // console.log(row, column, cellValue, index)
      // return cellValue

      // if (cellValue === 1) {
      //   return '正式工'
      // } else {
      //   return '临时工'
      // }
      // ----优雅写法----
      // return cellValue === 1 ? '正式工' : '临时工'

      // 思考: 如果后期工种增多, 比如: 1->正式工, 2->钟点工, 3->外包工, 0->未知
      // 方案: 枚举, 把这种映射关系抽离到独立文件中, 项目中引入即可
      const res = employees.hireType.find(item => {
        console.log(item.id, cellValue)
        return item.id === +cellValue
      })
      // console.log(res)
      return res ? res.value : '未知'
    },
    // 6. 删除一条记录
    handleDel(id) {
      this.$confirm('您确定删除该员工信息吗?', '温馨提示', { type: 'warning' }).then(async() => {
        const res = await reqDelEmployee(id)
        this.$message.success(res.message)
        // 特殊处理
        if (this.list.length === 1 && this.page > 1) {
          this.page--
        }
        this.getUserList()
      }).catch(() => {
        console.log('点击了取消')
      })
    },
    // 7. 处理添加成功后操作
    handleAddEmployee() {
      this.showAddDialog = false
      this.getUserList()
    },
    // 8. 处理Excel导出
    async handleExcelExport() {
      // 8.0 初始数据
      const headersArr = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
      const headersRelations = {
        '姓名': 'username',
        '手机号': 'mobile',
        '入职日期': 'timeOfEntry',
        '聘用形式': 'formOfEmployment',
        '转正日期': 'correctionTime',
        '工号': 'workNumber',
        '部门': 'departmentName'
      }

      // 8.1 获取所有的员工列表
      const { data: { rows }} = await reqGetUserList(1, this.total)
      // console.log(rows)

      // 8.2 把 对象型数组 转成 数组型数组
      const resArr = this.transObjArrToListArr(rows, headersArr, headersRelations)
      console.log(resArr)

      // 多表头
      const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
      // 合并单元格
      const merges = ['A1:A2', 'B1:F1', 'G1:G2']

      // 8.3 导出Excel
      this.downloadLoading = true
      import('@/vendor/Export2Excel').then(excel => {
        excel.export_json_to_excel({
          // 表头
          header: headersArr,
          // 主体内容
          data: resArr,
          filename: '员工信息表',
          multiHeader,
          merges
        })
        this.downloadLoading = false
      })
    },
    // 9. 把 对象型数组 转成 数组型数组
    transObjArrToListArr(rows, headersArr, headersRelations) {
      // console.log(rows, headersArr, headersRelations)
      // rows决定了大数组中有多少个小数组
      // headersArr决定了小数组中有多少个内容
      // 9.1 定义一个新的大数组
      const bigArr = []
      // 9.2 遍历对象型数组中的数据
      rows.forEach((item) => {
        // 9.3 创建一个小数组
        const smallArr = []
        // 9.4 遍历头部数据数组
        headersArr.forEach((key) => {
          // 9.4.1 根据 中文键名 找到 英文键名
          const englishKey = headersRelations[key]
          // 9.4.2 根据 英文键名 从原始对象中取出内容
          let value = item[englishKey]

          // 日期格式处理
          if (['timeOfEntry', 'correctionTime'].includes(englishKey)) {
            value = dayjs(item[englishKey]).format('YYYY年MM月DD日')
          }

          // 聘用形式格式处理
          if (englishKey === 'formOfEmployment') {
            const obj = employees.hireType.find((item) => {
              return item.id === +value
            })
            value = obj ? obj.value : '未知'
          }

          // 9.4.3 把取出的内容放到小数组中
          smallArr.push(value)
        })
        // 9.5 把小数组放入大数组
        bigArr.push(smallArr)
      })
      // console.log(bigArr)
      // 9.6 返回大数组
      return bigArr
    },
    // 10. 点击头像
    handleImgClick(imgUrl) {
      if (!imgUrl) return
      // vue中DOM是异步更新的
      this.showImgDialog = true
      this.$nextTick(() => {
        // 生成二维码
        QRCode.toCanvas(this.$refs.staffCanvas, imgUrl)
      })
    },
    // 11. 点击分配角色
    handleRole(userId) {
      // console.log(userId)
      // 1. 展示对话框
      this.showRoleDialog = true
      // 2. 保存用户id
      this.userId = userId
    }
  }
}
</script>

<style lang="scss" scoped>
  .staff-photo{
    width: 80px;
    height: 80px;
    border-radius: 50%;
  }
</style>
